iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Security

我逆向你逆向我的逆向工程膩系列 第 28

Dx28 - 靜態反逆向技術

  • 分享至 

  • xImage
  •  

由於靜態反逆向技術有很多種類型,今天將會演示幾項常見的反逆向技術。

以下都在 Win10 上執行。

本文章使用原始碼與成果位於
https://github.com/Dinlon5566/IT_Reverse_Engineering/tree/main/Dx28

PEB(Process Environment Block)

首先,PEB 裡面會記載著程序的各種狀態,裡面有很多參數助於我們判斷是否在 Debugger 中。

https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb

IsDebuggerPresent()

其中就包含著是否為 Debugger 狀態的 BeingDebugged,而在程式中可以透過 IsDebuggerPresent() 輕鬆地得知程式是否在 Debugger 狀態。

這份程式利用 IsDebuggerPresent() 來判斷是否為 Debugger 模式。

#include <iostream>
#include <Windows.h>
int main()
{
    if (IsDebuggerPresent()) {
        printf("Is Debuger mode!");
        return 0;
    }
    MessageBoxA(0,"Hello world","Dinlon",NULL);
}

那為了反制這個技術,來探討 IsDebuggerPresent() 是甚麼運行的 :

  1. 首先利用字串引用來快速到達主函式。

https://ithelp.ithome.com.tw/upload/images/20221012/20135675JM8F6L8VEg.png

  1. 看到判斷 Debugger 模式的分支點

https://ithelp.ithome.com.tw/upload/images/20221012/20135675GTyrPnbUuv.png

0x401040 這個位置 Call 了 IsDebuggerPresent()

0x401048 若判斷為正常執行則跳到 0x40105A 繼續運行

  1. 進入 call 的 IsDebuggerPresent() 函數位置。

https://ithelp.ithome.com.tw/upload/images/20221012/20135675MUhx2qGix2.png

可以看到這個函式十分簡單,就是引用了 FS 暫存器 +30 的位置得到 PEB 位置,然後再取用 PEB +2 就有 BeingDebugged 的值了。不過說著簡單,來看實際的位置吧。

  1. 首先這是 FS 的位置。

https://ithelp.ithome.com.tw/upload/images/20221012/20135675O6DTf1d8rb.png

+30 的位置是 0x3C5030,取一個 DWORD 就是 0x003C2000PEB 的位置。

  1. 查看 PEB

https://ithelp.ithome.com.tw/upload/images/20221012/20135675Uvjdwu7MDz.png

看到了 PEB+2 的數值是 1 ,代表是 Debugger 模式。把它改成 0x00 ,然後運行。

https://ithelp.ithome.com.tw/upload/images/20221012/20135675JERjRu6B8U.png

成功解除。


NtGlobalFlag

透過觀察 PEB0x68 位置也可以查出是否在 debugger 中,若是符合已條件 :

FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)

值將會是 0x70,此時就查的出程式是運行在反編譯器中的 。

https://ithelp.ithome.com.tw/upload/images/20221012/20135675YRYqVVXu6V.png

#include <iostream>
#include <Windows.h>
DWORD isDebuger()
{
    __asm
    {
        mov eax, fs: [0x30]
        movzx eax, dword ptr[eax + 0x68]
    }
}

int main()
{
    if (isDebuger()) {
        printf("Is Debuger mode!");
        return 0;
    }
    MessageBoxA(0, "Hello world", "Dinlon", NULL);
}

反制方法 : 跟上面一樣,把 PEB + 0x68 變成 0 就好了。


下面的就不是透過 PEB 來進行檢查了。

CheckRemoteDebuggerPresent()

透過這個函數可以知道程序是否在被遠程 Debugger 中。

#include <iostream>
#include <Windows.h>
BOOL isCRDP() {
    BOOL dbg;
    if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &dbg) && dbg) {
        return 1;
    }
    return 0;
}
int main()
{
    if (isCRDP()) {
        printf("Is Debuger mode!");
        return 0;
    }
    MessageBoxA(0, "Hello world", "Dinlon", NULL);
}

反制方法 : 由於改變他引用的數值過於麻煩,我會選擇 Hook 這個 API 直接把他忽略。


上一篇
Dx27 - 反逆向技術
下一篇
Dx29 - 動態反逆向技術
系列文
我逆向你逆向我的逆向工程膩31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言